<cfcomponent extends="assets.csac.com.Base">

	<cfscript>
        import assets.csac.com.service.OrderProductService;
		this.service = new OrderProductService();
	</cfscript>

	<cffunction name="get" output="false" access="remote" returntype="assets.csac.com.bo.OrderProduct">
		<cfreturn this.service.get(argumentCollection = arguments) />
	</cffunction>
	
	<cffunction name="query" output="false" access="public" returntype="query">
		<cfreturn this.service.read(argumentCollection = arguments) />
	</cffunction>
	
	<cffunction name="save" output="false" access="public" returntype="any">
		 <cfscript>
			var orderProduct = "";
			var orderProduct_ = this.service.get(Order_Product_ID = arguments.Order_Product_ID);
			var args = "";
			var productGateway = new assets.csac.com.gateway.ProductGateway();
			var product = "";
			var orderGateway = new assets.csac.com.gateway.OrderGateway();
			var order = "";
			var quantityProperty = "";
			var quantityAdjustment = 0;
			var totalQuantity = 0;
			var overQuantity = 0;
			var productStock = 0;
			var pArgs = "";
			var warnStock = false;
			if (IsInstanceOf(arguments[1], "assets.csac.com.bo.OrderProduct")) {
				orderProduct = arguments[1];
			} else {
				args = {};
				StructAppend(args, arguments);
				args.obj = Duplicate(orderProduct_);
				orderProduct = this.service.load(argumentCollection = args);
			}
			order = orderGateway.get(Order_ID = orderProduct.getOrder_ID());
			product = productGateway.get(Product_ID = orderProduct.getProduct_ID());
			// Validate, determine stock requirement
			if (orderProduct.getOrder_Product_ID() eq 0 and product.getDownload_Only()) {
				return "Download only";			
			// quantiy of 0, delete
			} else if (orderProduct.getQuantity() eq 0) {
				this.service.destroy(Order_Product_ID = orderProduct.getOrder_Product_ID());
				return "Removed from order (quantity 0)";
			// nothing changed, nothing to save
			} else if (orderProduct_.getQuantity() eq orderProduct.getQuantity() and orderProduct_.getQuantity_Shipped() eq orderProduct.getQuantity_Shipped()) {
				return "No change requested";
			// order shipped (assumes approved) or no change in data - can't Save
			} else if (IsDate(order.getShipped_Date())) {
				return "Shipped order cannot be updated";
			// order approved, not shipped, only updates to Quantity_Shipped
			} else if (IsDate(order.getApproved_Date()) and NOT IsDate(order.getShipped_Date())) {
				if (orderProduct_.getQuantity_Shipped() eq 0 and orderProduct.getQuantity_Shipped() gt 0) {
					// revert quantity
					orderProduct.setQuantity(orderProduct_.getQuantity());
					quantityAdjustment = orderProduct.getQuantity_Shipped() - orderProduct.getQuantity();
					totalQuantity = orderProduct.getQuantity_Shipped();
					quantityProperty = "Quantity_Shipped";
				} else if (orderProduct.getQuantity_Shipped() neq orderProduct_.getQuantity_Shipped()) {
					// revert quantity
					orderProduct.setQuantity(orderProduct_.getQuantity());
					quantityAdjustment = orderProduct.getQuantity_Shipped() - orderProduct_.getQuantity_Shipped();
					totalQuantity = orderProduct.getQuantity_Shipped();
					quantityProperty = "Quantity_Shipped";
				} else {
					return "Quantity cannot change for approved order";
				}
			// order not approved, only updates to Quantity
			} else if (NOT IsDate(order.getApproved_Date())) {
				if (orderProduct_.getQuantity() neq orderProduct.getQuantity()) {
					// revert quantity shipped
					orderProduct.setQuantity_Shipped(orderProduct_.getQuantity_Shipped());
					quantityAdjustment = orderProduct.getQuantity() - orderProduct_.getQuantity();
					totalQuantity = orderProduct.getQuantity();
					quantityProperty = "Quantity";
				} else {
					return "Quantity shipped cannot change for unapproved order";	
				}
			// approved date, no shipped date - invalid
			} else {
				return "Invalid - shipped not approved";
			}
			// Adjust stock if stockAdjustment <> 0
			if (quantityAdjustment neq 0) {
				productStock = productGateway.checkStock(Product_ID = orderProduct.getProduct_ID());
				productStock = productStock[orderProduct.getProduct_ID()];
				if (IsNumeric(productStock.Maximum)) {
					// replace stock
					if (quantityAdjustment lte 0) {
						productStock.Stock = productStock.Stock - quantityAdjustment;
					// depleat stock
					} else if (quantityAdjustment gt 0) {
						if (totalQuantity gt productStock.Maximum) {
							overQuantity = totalQuantity - productStock.Maximum;
							quantityAdjustment = quantityAdjustment - overQuantity;
							totalQuantity = totalQuantity - overQuantity;
							productStock.Stock = productStock.Stock - quantityAdjustment;
							if (quantityProperty eq "Quantity") {
								orderProduct.setQuantity(totalQuantity);
							} else if (quantityProperty eq "Quantity_Shipped") {
								orderProduct.setQuantity_Shipped(totalQuantity);
							}
						} else if (totalQuantity lte productStock.Maximum) {
							productStock.Stock = productStock.Stock - quantityAdjustment;
						}
					}
					if (product.getStock() lte product.getStock_Warn() and productStock.Stock lt productStock.Stock_Warn) {
						warnStock = true;
					}
					// save Product Stock
					pArgs = {};
					pArgs.Product_ID = productStock.Product_ID;
					pArgs.Stock = productStock.Stock;
					product = productGateway.save(argumentCollection = pArgs);
				}
			}
			orderProduct.setOrder_Product_ID(this.service.save(orderProduct));
        </cfscript>
		<cfif warnStock or 1 eq 1>
			<cfmail to="clenz@csac.ca.gov" bcc="ken@syntric.com" from="epubs@csac.ca.gov" subject="ePubs Stock Warning" type="html">
				<p>The stock for #product.getProduct()# is below the stock warning amount.</p>
				<p>The current stock amount is #productStock.Stock#.</p>
			</cfmail>		
		</cfif>		
		<cfreturn orderProduct />
	</cffunction>
	
	<cffunction name="delete" output="false" access="public" returntype="boolean">
		<cfreturn this.service.destroy(argumentCollection = arguments) />
	</cffunction>
	
	<!--- <cffunction name="checkStock" output="false" access="public" returntype="struct">
		<cfargument name="Quantity" type="numeric" required="yes" />
		<cfargument name="Minimum" type="any" required="yes" />
		<cfargument name="Maximum" type="any" required="yes" />
		<cfargument name="Increment" type="any" required="yes" />
		<cfscript>
			var ret = StructNew();
			StructAppend(ret, arguments);
			ret.valid = true;
			ret.error = "";
			ret.alt_quantity = "";
			// minimum check
			if (IsNumeric(arguments.Minimum)) {
				if (arguments.Quantity lt arguments.Minimum) {
					// below minimum
					ret.valid = false;
					ret.error = "Below minimum of " & arguments.Minimum;
					ret.alt_quantity = arguments.Minimum;
				}
			}
			// maximum check
			if (IsNumeric(arguments.Maximum)) {
				if (arguments.Quantity gt arguments.Maximum) {
					// exceeds maximum
					ret.valid = false;
					ret.error = "Over maximum of " & arguments.Maximum;
					ret.alt_quantity = arguments.Maximum;
				}
			}
			// increment check
			if (IsNumeric(arguments.Increment)) {
				if (!(arguments.Quantity MOD arguments.Increment) eq 0) {
					// invalid increment
					ret.valid = false;
					ret.error = "Not increment of " & arguments.Increment;
					ret.alt_quantity = Int(arguments.Quantity/arguments.Increment) * arguments.Increment;
				}
			}
			return ret;
		</cfscript>
	</cffunction> --->

</cfcomponent>